package com.yunjing.udpsendreceivedata;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;


public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    private InetAddress mAddress;
    private DatagramSocket mSocket = null;
    /**
     * 发送给整个局域网：255.255.255.255,局域网网段：192.168.0.255
     */
    private String mBroadCastIp = "192.168.2.16";
    /**
     * 发送方和接收方需要端口一致
     */
    private int mPort = 10000;

    private static final String TAG = "MainActivityTag";
    private EditText mEtContent;
    private TextView mTvReceiveContent;
    private EditText mEtIp;
    private DatagramSocket datagramSocket;
    private DatagramPacket datagramPacket;
    private final int MSG_RECEIVE_DATA_WHAT = 1000;
    private boolean noExecuteRun = false;
    private Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_RECEIVE_DATA_WHAT:
                    String result = (String) msg.obj;
                    //往textview上追加数据
                    mTvReceiveContent.append(result + "\n");
                    Log.d(TAG, "handleMessage--result: " + result);
                    break;
            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mEtIp = findViewById(R.id.et_ip);
        mEtContent = findViewById(R.id.et_content);
        mTvReceiveContent = findViewById(R.id.tv_receive_content);
        findViewById(R.id.btn_udp_send).setOnClickListener(this);

    }

    @Override
    protected void onStart() {
        super.onStart();
        udpReceive();
    }

    /**
     * udp接收数据
     */
    private void udpReceive() {

        //魅族Note6机型上测试，不支持在主线程接收数据，其他两个华为的平板测试支持主线程接收
        new Thread(() -> {
            try {
                datagramSocket = new DatagramSocket(mPort);
                // 2.创建一个数据包接收数据
                byte[] buffer = new byte[1024];
                datagramPacket = new DatagramPacket(buffer, buffer.length);
                //定时100ms接收数据
                App.getThreadPoolManager().getScheduledThread().scheduleWithFixedDelay(workTimerTask, 0, 100, TimeUnit.MILLISECONDS);

            } catch (SocketException e) {
                e.printStackTrace();
            }
        }).start();

    }

    private Runnable workTimerTask = new Runnable() {
        @Override
        public void run() {
            if (!noExecuteRun) {
                // 3.等待接受数据
                try {
                    datagramSocket.receive(datagramPacket);
                    // 4.取出数据
                    String result = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
                    Log.d(TAG, "receiveData---result-接收数据: " + result);
                    //发送到主线程更新显示
                    handler.sendMessage(handler.obtainMessage(MSG_RECEIVE_DATA_WHAT, result));
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d(TAG, "receiveData---接收数据异常: " + e.getMessage());
                }
            }
        }
    };


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_udp_send:

                String inputContent = mEtContent.getText().toString().trim();
                if (TextUtils.isEmpty(inputContent)) {
                    Toast.makeText(this, "请输入要发送的内容！", Toast.LENGTH_SHORT).show();
                    return;
                }
                Log.d(TAG, "onClick---inputContent: " + inputContent);
                sendUDPMessage(inputContent);

                break;

        }
    }

    /**
     * 发送数据
     *
     * @param msg 消息
     */
    public void sendUDPMessage(final String msg) {

        // 初始化socket
        try {
            mSocket = new DatagramSocket();
        } catch (SocketException e) {
            e.printStackTrace();
            Log.d(TAG, "sendUDPMessage-SocketException: " + e.getMessage());
        }
        if (!TextUtils.isEmpty(mEtIp.getText().toString().trim())) {
            mBroadCastIp = mEtIp.getText().toString().trim();
        }
        try {
            mAddress = InetAddress.getByName(mBroadCastIp);
        } catch (UnknownHostException e) {
            e.printStackTrace();
            Log.d(TAG, "sendUDPMessage-UnknownHostException: " + e.getMessage());
        }

        ThreadPoolManager.getInstance().startTaskThread(() -> {
            try {

                byte[] mSendBuf = msg.getBytes("utf-8");
                DatagramPacket packet =
                        new DatagramPacket(mSendBuf, mSendBuf.length, mAddress, mPort);
                mSocket.send(packet);
                mSocket.close();
                Log.e(TAG, "sendUDPMessage msg：" + msg);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                Log.d(TAG, "run: UnsupportedEncodingException:" + e.getMessage());
            } catch (IOException e) {
                e.printStackTrace();
                Log.d(TAG, "run---IOException: " + e.getMessage());
            }

        }, "");
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeMessages(MSG_RECEIVE_DATA_WHAT);
        noExecuteRun = true;
    }
}